﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Security;
using TRL.DataAccessLayer;


namespace TRL.TRLAdmin.Members
{
    public partial class AddEditMember : System.Web.UI.Page
    {
        // Private variables
        private bool _showMembershipKitHistory;
        
        //
        // Properities
        //
        public enum Mode { AddMember, EditMember }
        
        /// <summary>
        /// This property controls the mode of the form. It's either
        /// AddMember or EditMember. Based on this property the form
        /// is rendered differently and either an edit or insert serverside action
        /// happens.
        /// </summary>
        public Mode OperationMode { private set; get; }

        // The below two properties are used when editing a member. They can either be specified
        // via a QueryString paramater (as when editing a member via ViewMembers.aspx)
        // or by their properties (as happens when a member is added or edited and then we display
        // the edit member form.
        private int? _membershipId;
        public int? MembershipId
        {
            private set
            {
                this._membershipId = value;
                ViewState["MembershipId"] = value;
            }
            get
            {
                if (this._membershipId != null)
                {
                    return this._membershipId;
                }
                else 
                {
                    if (Request.QueryString["MembershipId"] != null)
                        return Int32.Parse(Request.QueryString["MembershipId"]);
                    else
                        return Int32.Parse(ViewState["MembershipId"].ToString());
                }
            }
        }
        private string _displayName;
        public string DisplayName
        {
            private set
            {
                this._displayName = value;
                ViewState["DisplayName"] = value;
            }
            get
            {
                if (this._displayName != null)
                {
                    return this._displayName;
                }
                else
                {
                    if (Request.QueryString["DisplayName"] != null)
                        return Request.QueryString["DisplayName"].ToString();
                    else
                        return ViewState["DisplayName"].ToString();
                }
            }
        }


        //
        // Methods
        //
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if ((string.IsNullOrEmpty(Request.QueryString["mode"]) == true) || (Request.QueryString["mode"].ToString() == "insert"))
                {
                    OperationMode = Mode.AddMember;
                    FormView1.ChangeMode(FormViewMode.Insert);
                }
                else
                {
                    OperationMode = Mode.EditMember;
                    FormView1.ChangeMode(FormViewMode.Edit);
                }
            }
            else
            {
                clearMessages();
                if (FormView1.CurrentMode == FormViewMode.Insert)
                    OperationMode = Mode.AddMember;
                else
                    OperationMode = Mode.EditMember;
            }
        }

        /// <summary>
        /// Called by FormView DataBound event. Displays the approriate insert or edit button based on the mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void FormView1_DataBound(object sender, EventArgs e)
        {
            var insertButton = FormView1.FindControl("InsertButton") as Button;
            var updateButton = FormView1.FindControl("UpdateButton") as Button;
            var updateAndSendMemKitButton = FormView1.FindControl("UpdateAndSendMemKitButton") as Button;
            var updateAndMarkMemKitSentButton = FormView1.FindControl("UpdateAndMarkMemKitSent") as Button;

            if (OperationMode == Mode.AddMember)
            {
                insertButton.Visible = true;
                updateButton.Visible = false;
                updateAndSendMemKitButton.Visible = false;
                updateAndMarkMemKitSentButton.Visible = false;
            }
            else
            {
                insertButton.Visible = false;
                updateButton.Visible = true;

                using (var dc = new DataClasses1DataContext())
                {
                    var needWelcomeKit =
                        (from u in dc.Members
                         where u.membershipId == MembershipId
                         select u.needWelcomeKit).First();
                    if (needWelcomeKit)
                    {
                        // If the member needs a welcome kit display button "Update and Mark as Mem Kit Sent"
                        // as if the member needs a welcome kit, this a valid option through the UI.
                        updateAndSendMemKitButton.Visible = false;
                        updateAndMarkMemKitSentButton.Visible = true;
                    }
                    else
                    {
                        // Membership does not currently need a welcome kit, so display button "Update and Mark as Needing Mem Kit"
                        // as this is only a valid UI option if the member does not need a weclome kit (ie, it received on a year ago).
                        updateAndSendMemKitButton.Visible = true;
                        updateAndMarkMemKitSentButton.Visible = false;                    
                    }
                }

                var memKitHistoryPanel = FormView1.FindControl("MembershipKitHistoryFields") as Panel;
                if (_showMembershipKitHistory)
                    memKitHistoryPanel.Visible = true;            
            }
        }

        /// <summary>
        /// Called when Cancel Button is clicked. Either clears form if in Add Member mode, or if in Edit Member mode
        /// redirects users to View Members page.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void CancelButton_Click(object sender, EventArgs e)
        {
            if (OperationMode == Mode.AddMember)
            {
                Response.Redirect("AddEditMember.aspx", true);
            }
            else
            {
                Response.Redirect("ViewMembers.aspx", true);
            }
        }

        /// <summary>
        /// Called by the FormView OnItemInserting. Validates that the new membership can be created
        /// and marks that the member need a membership kit.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ValidateMember(object sender, FormViewInsertEventArgs e)
        {
            // These two statements convert blank date values to null.
            // If not done an error occurs on insert.
            object dob = e.Values["dob"];
            if (dob.ToString() == "")
                e.Values["dob"] = null;

            object secondDob = e.Values["secondDob"];
            if (secondDob.ToString() == "")
                e.Values["secondDob"] = null;
            
            string strSQLconnection = ConfigurationManager.ConnectionStrings["trladminConnectionString"].ToString();
            using (var sqlConnection = new SqlConnection(strSQLconnection))
            {
                var sqlCommand = new SqlCommand(@"
                    SELECT TOP 1 membershipId FROM Memberships 
                    WHERE 
                        (phoneNumber <> '' AND phoneNumber = @phoneNumber)
                        OR (firstName = @firstName AND lastName = @lastName)", sqlConnection);
                sqlCommand.Parameters.AddWithValue("@phoneNumber", e.Values["phoneNumber"].ToString());
                sqlCommand.Parameters.AddWithValue("@firstName", e.Values["firstName"].ToString());
                sqlCommand.Parameters.AddWithValue("@lastName", e.Values["lastName"].ToString());
                sqlConnection.Open();
                if (sqlCommand.ExecuteScalar() != null)
                {
                    displayMessage(MessageType.Error, "A Member with that name or phone number already exists. The existing member should be updated instead of a new one created.");
                    e.Cancel = true;
                    return;
                }
            }

            e.Values["needWelcomeKit"] = true;
        }

        
        private enum MessageType { Success, Error }
        /// <summary>
        /// Displays an error message to the user.
        /// </summary>
        /// <param name="msg"></param>
        private void displayMessage(MessageType type, string msg)
        {
            if (type == MessageType.Error)
                message.CssClass = "alert alert-error";
            else
                message.CssClass = "alert alert-success";

            message.Visible = true;
            message.Text = msg;
        }

        /// <summary>
        /// Clears all error messages.
        /// </summary>
        private void clearMessages()
        {
            message.Visible = false ;
        }


        /// <summary>
        /// Called by the LinqDataSource when a member is selected. Adds the membershipId to the 
        /// WhereParameter.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void MemberSelecting(object sender, LinqDataSourceSelectEventArgs e)
        {
            ///TODO: See if we can remove this and use a ControlParmaters ASP.NET element
            ///to store.
            e.WhereParameters.Add("membershipId", MembershipId);
        }

        /// <summary>
        /// Called after LinqDataSource control has retrieved member to update but before
        /// renders form. We use this to display history of the membership kit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void MemberSeleced(object sender, LinqDataSourceStatusEventArgs e)
        {
            // Select the first member of results. There will always only be one member
            List<Member> members = (List<Member>)e.Result;
            var m = members[0];

            var insertButton = FormView1.FindControl("InsertButton") as Button;

            // If a userId is specified, use that as the full name to display
            if (m.welcomeKitLastSentByUserId != null)
            {
                using (var dc = new DataClasses1DataContext())
                {
                    var fullName =
                        (from u in dc.AdminUserInfos
                         where u.userId == m.welcomeKitLastSentByUserId
                         select u.fullName).First();
                    m.welcomeKitLastSentByFullName = fullName;
                }
                _showMembershipKitHistory = true;
            }
            else if (!String.IsNullOrEmpty(m.welcomeKitLastSentByFullName))
            {
                // Else is a ufser id is not specified and welcomeKitLastSentByFullName is specified,
                // display that. It'll display by default so we don't need to do any work.
                // Note that causes where welcomeKitLastSentByUserId would be null but 
                // welcomeKitLastSentByFullName would be set are when a user is deleted 
                // or from the old version of membership database.
                _showMembershipKitHistory = true;
            }
            else
            {
                _showMembershipKitHistory = false;
            }
        }

        /// <summary>
        /// Called when a member is requested to be updated but before the db is updated. 
        /// Used to set needWelcomeKit to true and who is editing user.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void MemberUpdating(Object sender, FormViewUpdateEventArgs e)
        {
            // These two statements convert blank date values to null.
            // If not done an error occurs on insert.
            object dob = e.NewValues["dob"];
            if (dob.ToString() == "")
                e.NewValues["dob"] = null;

            object secondDob = e.NewValues["secondDob"];
            if (secondDob.ToString() == "")
                e.NewValues["secondDob"] = null;
            

            if ((string)e.CommandArgument == "UpdateAndMarkNeedWelcomeKit")
            {
                e.NewValues["needWelcomeKit"] = true;
            }
            else if (e.CommandArgument.ToString() == "MarkWelcomeKitSent")
            {
                e.NewValues["needWelcomeKit"] = false;
                e.NewValues["welcomeKitLastSentOn"] = DateTime.Now;

                using (var dc = new DataClasses1DataContext())
                {
                    var loggedInUserId = (Guid)Membership.GetUser().ProviderUserKey;
                    var loggedInUserInfo =
                        (from u in dc.AdminUserInfos
                         where u.userId == loggedInUserId
                         select u).First();
                    e.NewValues["welcomeKitLastSentByFullName"] = loggedInUserInfo.fullName;
                    e.NewValues["welcomeKitLastSentByUserId"] = loggedInUserId;
                }
            }
        }
        

        /// <summary>
        /// Called by the LinqDataSource after an insert or update. If any database errors occured, gracefully display to user;
        /// otherwise re-render page in Edit Member mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void MemberInsertedOrUpdated(object sender, LinqDataSourceStatusEventArgs e)
        {
            if (e.Exception == null)
            {
                // Member has been sucecesfully added or updated.
                // Display message operation successfuly and setup page to be re-rendered in
                // Edit Member mode. 
                if (FormView1.CurrentMode == FormViewMode.Insert)
                    displayMessage(MessageType.Success, "Member has been successfully added.");
                else
                {
                    displayMessage(MessageType.Success, "Member has been successfully updated.");
                
                }
                OperationMode = Mode.EditMember;
                FormView1.DefaultMode = FormViewMode.Edit;
                var member = e.Result as Member;
                MembershipId = member.membershipId;
                DisplayName = member.firstName + " " + member.lastName;
            }
            else
            {
                // Error occured adding membership to database. Dipslay error message to user
                // and stay on page.
                displayMessage(MessageType.Error, "An error occured adding or updating this member. If this error continues contact TRL Web Administrator or TRL Web host with the following information: " + e.Exception.Message);
                e.ExceptionHandled = true;
                if (FormView1.CurrentMode == FormViewMode.Insert)
                {
                    // Subtle note:
                    // If the user was inserting, we have to change the DefaultMode to insert, so that the user gets displayed an insert form.
                    // Otherwise they'll get displayed an edit form as that's the DefaultMode of the FormVIew
                    FormView1.DefaultMode = FormViewMode.Insert;
                }
            }
        }

        /// <summary>
        /// Called by the FormView OnItemCreated when a row is being created. Sets up defaults.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void SetupDefaultsForMember(object sender, EventArgs e)
        {
            if (FormView1.CurrentMode == FormViewMode.Insert)
            {
                CheckBox sendPaperNewsletterCheckBox = FormView1.FindControl("sendPaperNewsletterCheckBox") as CheckBox;
                CheckBox sendENewsletterCheckBox = FormView1.FindControl("sendENewsletterCheckBox") as CheckBox;
                CheckBox okayToContactCheckBox = FormView1.FindControl("okayToContactCheckBox") as CheckBox;

                if (sendPaperNewsletterCheckBox != null)
                {
                    sendPaperNewsletterCheckBox.Checked = true;
                }

                if (sendENewsletterCheckBox != null)
                {
                    sendENewsletterCheckBox.Checked = true;
                }

                if (okayToContactCheckBox != null)
                {
                    okayToContactCheckBox.Checked = true;
                }
            }
        }

    }
}